#include <p32xxxx.h>
#include <plib.h>
#include "Bike_Display_ECM_Functions.h"
#include "Bike_Display_HW_Profile.h"

char ECMReceiveData[255];
char ECMSendData[255];

/*
The command set includes two one-byte commands, that are used to retrieve the ECM firmware 
version and a set of runtime data from the ECM.

Byte #	Meaning	    Values	    Remarks
1	    SOH	        0x01	    Start of Header
2	    Emittend	0x00	    From PC
3	    Recipient	0x42	    To ECM
4	    Data Size	0x02	    2 Bytes
5	    EOH	        0xFF	    End of Header
6	    SOT	        0x02	    Start of Text
7	    Data 1	    0x56        Get Version Command Code
                    0x43        Get Runtime Data
8	    Data 2(EOT)	0x03	    End of Text
9	    Checksum	0xE8	    XORed Checksum
*/
void ECMVersion_RuntimeData(char cDataSize, char cCommandCode) 
{
    char nCheckSum = 0;
    char nLoop = 0;
    
    ECMSendData[0] = SOH;
    ECMSendData[1] = PC;
    ECMSendData[2] = ECM;
    ECMSendData[3] = cDataSize;
    ECMSendData[4] = EOH;
    ECMSendData[5] = SOT;
    ECMSendData[6] = cCommandCode;
    ECMSendData[7] = EOT;
        
    //To calculate the checksum, XOR all elements of the array except the first one
    for(nLoop = 1; nLoop < 8; nLoop++)
    {
        nCheckSum = nCheckSum ^ ECMSendData[nLoop]; 
    }
    
    ECMSendData[8] = nCheckSum;
    SendDataToECM(ECMSendData, 9);
}

/* 
Communicating with the ECM to get any part of the EEPROM data as per table in ECMSpy
http://www.ecmspy.com/cgi-bin/ecm.cgi?ecm=8
Ckecksum calculation is done XOR Byte 2 to Checksum - 1
To ECM
Byte #	Meaning	    Values      Remarks
1	    SOH	        0x01	    Start of Header
2	    Emittend	0x00	    From PC
3	    Recipient	0x42	    To ECM
4	    Data Size	0x05	    5 Bytes
5	    EOH	        0xFF	    End of Header
6	    SOT	        0x02	    Start of Text
7	    Data 1      0x52        Get Command
                    0x57        Set Command
8	    Data 2	    0x00	    Page Offset
9	    Data 3	    0x01	    Page No.
10	    Data 4	    0x01	    Number of Bytes
11	    Data 5(EOT)	0x03	    End of Text
12	    Checksum	0xEB	    XORed Checksum
*/


/*
Reply from ECM
Byte #	Meaning	    Values	    Remarks
1	    SOH	        0x01	    Start of Header
2	    Emittend	0x42	    From ECM
3	    Recipient	0x00	    To PC
4	    Data Size	0x03	    3 Bytes
5	    EOH	        0xFF	    End of Header
6	    SOT	        0x02	    Start of Text
7	    Data 1(ACK) 0x06        Success
                    else        Error Indicator
8	    Data 2	    0x00	    EEPROM Data
9	    Data 3(EOT)	0x03	    End of Text
10	    Checksum	0xE0	    XORed Checksum

In addition to those pages, that are physically present in the EEPROM, 
the ECM firmware supports a virtual page 32 (0x20 in hexadecimal). 
Writing values to the page offset 0 of this page trigger pre-defined functions, 
such as a TPS reset or running various tests. The example below shows a "Clear DTC" command. 
Just as with the EEPROM write commands, the ECM responds with a single ACK response, containing no data.

Byte #	Meaning	    Values	    Remarks
1	    SOH	        0x01	    Start of Header
2	    Emittend	0x00	    From PC
3	    Recipient	0x42	    To ECM
4	    Data Size	0x05	    5 Bytes
5	    EOH	        0xFF	    End of Header
6	    SOT	        0x02	    Start of Text
7	    Data 1	    0x57	    Command
8	    Data 2	    0x00	    Page Offset
9	    Data 3	    0x20	    Virtual Page No.
10	    Data 4	    0x01        Clear Codes
                    0x02        Front Coil
                    0x03        Rear Coil
                    0x04        Tachometer  Data Byte
                    0x05        Fuel Pump   (Device Selector or Reset Code)
                    0x06        Front Inj.
                    0x07        Rear Inj.
                    0x08        TPS Reset
                    0x09        Fan
                    0x0a        Exh. Valve   
11	    Data 5(EOT)	0x03	    End of Text
12	    Checksum	0xCF	    XORed Checksum

Reading one byte from virtual page 32, offset 0 returns the current ECM status. 
A value of 0x00 signals normal operation, any other value indicates a busy state.
*/

//Send the data to ECM

void SendDataToECM(char *cBuffer, UINT8 nSize)
{
    while(nSize)
    {
        while(!UARTTransmitterIsReady(ECMUART));
        
        UARTSendDataByte(ECMUART, *cBuffer);

        cBuffer++;
        nSize--;
    }
    while(!UARTTransmissionHasCompleted(ECMUART));
}

// Get the data from ECM
char GetDataFromECM(char *cBuffer, UINT8 nMaxSize)
{
    UINT8 nNumChar = 0;

    while(nNumChar < nMaxSize)
    {
        char character;

        while(!UARTReceivedDataIsAvailable(ECMUART));

        cBuffer[nNumChar] = UARTGetDataByte(ECMUART);

        if(cBuffer[nNumChar] == '\r') break;

        nNumChar++;
    }
    cBuffer[254] = 0x06;
    
    return nNumChar;
}
